package com.pingan.haofang.searchcloud;

import java.util.Arrays;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.pingan.haofang.searchcloud.batch.common.BatchResult;
import com.pingan.haofang.searchcloud.batch.common.BatchRunInstance;
import com.pingan.haofang.searchcloud.batch.common.BatchRunner;
import com.pingan.haofang.searchcloud.batch.common.BatchRunnerFactory;

/**
 * 批处理执行入口
 *
 * @author LUYI374
 * @date 2017年3月7日
 * @since 1.0.0
 */
@SpringBootApplication
@ServletComponentScan
@ComponentScan
@EnableTransactionManagement(order = 1)
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class,
 DataSourceTransactionManagerAutoConfiguration.class, RabbitAutoConfiguration.class })
public class BatchMain {

    static Logger LOG = LoggerFactory.getLogger(BatchMain.class);

    public static void main(String[] args) {
        //检查参数是否合法
        checkArgs(args);

        SpringApplication application = new SpringApplication(BatchMain.class);

        boolean webEnable = false;
        try {
            webEnable = Boolean.valueOf(System.getProperty("webEnable"));
        } catch (Exception e) {
        }
        application.setWebEnvironment(webEnable);

        Properties defaultProperties = new Properties();
        defaultProperties.setProperty(args[0], "true");

        application.setDefaultProperties(defaultProperties);
        application.run(args);

        String runnerName = args[0];
        BatchRunInstance instance = BatchRunnerFactory.getRunner(runnerName);

        if (instance == null) {
            throw new ExceptionInInitializerError("cannot found runner [" + runnerName + "], please check");
        }

        String[] runnerArgs = null;
        if (args.length > 1) {
            runnerArgs = new String[args.length - 1];
            System.arraycopy(args, 1, runnerArgs, 0, runnerArgs.length);
        } else {
            runnerArgs = new String[0];
        }

        // 执行，区分常驻与非常驻
        if (!instance.getConfig().permanent()) {
            runNoPermanent(instance, runnerArgs);
        } else {
            runInPermanent(instance, runnerArgs);
        }
    }

    /**
     * 非常驻模式运行
     *
     * @param instance
     * @param args
     */
    private static void runNoPermanent(BatchRunInstance instance, String[] args) {

        Object runner = instance.getRunner();
        if (!(runner instanceof BatchRunner)) {
            LOG.error("batch job with no permanent must impl from BatchRunner");
            System.exit(BatchResult.FAIL.getValue());
            return;
        }

        String runnerName = instance.getConfig().value();
        try {
            LOG.info("now start execute batch runner:[{}], args:{}", runnerName, Arrays.toString(args));

            BatchResult result = ((BatchRunner) runner).run(args);
            if (result != null) {
                LOG.error("execute batch runner finish:[{}], result:[{}], args:{}", runnerName, result,
                        Arrays.toString(args));
                System.exit(result.getValue());
                return;
            }
        } catch (Throwable e) {
            LOG.error("execute batch runner failed:[{}], args:{}", runnerName, Arrays.toString(args), e);
        }
        System.exit(BatchResult.FAIL.getValue());
    }

    /**
     * 常驻进程模式
     *
     * @param instance
     * @param args
     */
    private static void runInPermanent(BatchRunInstance instance, String[] args) {
        Object runner = instance.getRunner();
        if (runner instanceof BatchRunner) {
            ((BatchRunner) runner).run(args);
        }
    }

    /**
     * 检查参数是否合法
     *
     * @param args
     */
    private static void checkArgs(String[] args) {
        if (args.length < 1) {
            throw new ExceptionInInitializerError("arg is illegal, eg: BatchMain batchJobName args...");
        }
    }
}
